import html2canvas from 'html2canvas';
import { ElMessage } from 'element-plus';
import { nextTick } from 'vue';
/**
 * 生成截图并返回 Base64 图片 URL
 * @param {Object} options - 配置参数对象
 * @param {Ref} options.htmlCanvas - 包含待截图内容的 DOM 元素的 Vue ref 引用
 * @param {Ref} options.LOGO_URL - 包含 logo 图片 URL 的 Vue ref 引用
 * @param {Object} options.dialogForm - 表单对象，包含背景图片的 URL 信息
 * @param {Ref} options.loading - Vue ref，控制是否显示加载状态
 * @param {Ref} options.htmlImg - Vue ref，用于存储生成的 Base64 图片 URL
 * @returns {Promise<string>} - 返回生成的 Base64 图片 URL
 */
export const generateScreenshotImage = async ({
  htmlCanvas,
  LOGO_URL,
  dialogForm,
  htmlImg,
}) => {
  // 隐藏不需要的元素
  const hideElements = () => {
    const dragEditBoxes = document.querySelectorAll('.drag-edit-box');
    const zoneLogo = document.querySelector('.zone-logo');
    // 让DOM完成渲染后再获取加载动画元素
    nextTick(() => {
      const loadingSpinner = document.querySelector('.el-loading-spinner');
      if (loadingSpinner) {
        console.log('加载动画元素已获取:', loadingSpinner);
        loadingSpinner.style.top = '25%';
      }
    });

    dragEditBoxes.forEach((el) => {
      el.style.display = 'none';
    });
    if (zoneLogo) {
      zoneLogo.style.display = 'none';
    }
  };

  // 恢复被隐藏的元素
  const showElements = () => {
    const dragEditBoxes = document.querySelectorAll('.drag-edit-box');
    const zoneLogo = document.querySelector('.zone-logo');
    nextTick(() => {
      const loadingSpinner = document.querySelector('.el-loading-spinner');
      if (loadingSpinner) {
        loadingSpinner.style.top = '50%';
      }
    });
    dragEditBoxes.forEach((el) => {
      el.style.display = '';
    });
    if (zoneLogo) {
      zoneLogo.style.display = '';
    }
  };

  /**
   * 容错处理的图片加载函数
   * @param {string} url - 图片的 URL
   * @returns {Promise<void>} - 图片加载成功 resolve，失败 reject 但继续处理
   */
  const loadImageWithFallback = (url) => {
    return new Promise((resolve) => {
      const img = new Image();
      img.src = url;

      img.onload = () => resolve(); // 成功加载
      img.onerror = () => {
        console.warn(`图片加载失败: ${url}`); // 图片加载失败但继续处理
        resolve(); // 图片加载失败也 resolve，以便流程继续
      };
    });
  };

  /**
   * 检查 logo 和背景图片是否加载完成
   * @param {string} logoURL - logo 图片的 URL
   * @param {string} bgURL - 背景图片的 URL
   * @returns {Promise<void>} - 图片加载完成后 resolve，否则跳过
   */
  const checkImagesLoaded = (logoURL, bgURL) => {
    return Promise.all([
      loadImageWithFallback(logoURL),
      loadImageWithFallback(bgURL),
    ]);
  };

  /**
   * 执行截图并返回 Base64 图片 URL
   * @param {HTMLElement} htmlCanvas - 包含要截图内容的 DOM 元素
   * @returns {Promise<string>} - 截图生成的 Base64 图片 URL
   */
  const captureScreenshot = (htmlCanvas) => {
    return html2canvas(htmlCanvas, {
      scale: 4, //按比例增加分辨率 (2=双倍).  
      dpi: window.devicePixelRatio * 2, //设备像素比
      useCORS: true, // 允许跨域图片加载
      backgroundColor: null, // 确保透明背景正确渲染
      scrollX: 0, // 固定滚动位置
      scrollY: 0,
      width: htmlCanvas.scrollWidth, // 获取整个容器的宽度
      height: htmlCanvas.scrollHeight, // 获取整个容器的高度
    })
      .then((canvas) => {
        return canvas.toDataURL('image/png'); // 返回 Base64 编码的图片
      })
      .catch((error) => {
        throw error; // 捕捉截图过程中产生的错误
      });
  };

  // 主生成函数逻辑
  try {
    // 获取截图前的原始高度
    const originalHeight = document.querySelector('.leftdiv').style.height;
    // 禁用滚动，让内容完全显示
    document.querySelector('.leftdiv').style.height = 'auto';

    // 如果 htmlCanvas 未传入，直接返回
    if (!htmlCanvas) return;

    // 隐藏不需要的元素
    hideElements();

    // 检查 logo 和背景图片是否加载完成，但允许加载失败的图片继续流程
    await checkImagesLoaded(LOGO_URL, dialogForm.img_url);

    // 执行截图
    const screenshotURL = await captureScreenshot(htmlCanvas);
    htmlImg = screenshotURL; // 将生成的 Base64 图片 URL 存入 htmlImg

    // 恢复原来的滚动状态和页面状态
    document.querySelector('.leftdiv').style.height = originalHeight;
  } catch (error) {
    ElMessage.error('截图失败');
  } finally {
    showElements(); // 恢复被隐藏的元素
  }
  return htmlImg; // 返回生成的图片 URL
};
